package com.or.common.base;

import android.os.Bundle;
import androidx.activity.ComponentActivity;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.ViewModelProvider;

import com.blankj.utilcode.util.BarUtils;
import com.or.common.R;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract class CMBaseActivity<V extends ViewDataBinding, VM extends CMBaseViewModel> extends ComponentActivity {
    protected V binding;
    protected VM viewModel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initStatusBar();
        initViewDataBinding(savedInstanceState);
        initView();
        initListener();
        initData();
        initViewObservable();
    }

    private void initStatusBar() {
        // 设置状态栏是否可见
        BarUtils.setStatusBarVisibility(this, true);

        // 设置状态栏的内容的亮度模式。默认false，内容为白色；true：内容为黑色。
        // 某些情况下，如果主题为白色，那么默认的亮度模式下，由于色值相近会看不清状态栏的通知等其他内容
        BarUtils.setStatusBarLightMode(this, false);

        // 改变状态栏的颜色。true：添加到DecorView上，即遮挡了原本的顶部内容；false：添加到R.id.content（setContentView()）
        // 内容中，即沉浸浮现在布局之上透明。
        BarUtils.setStatusBarColor(this, ContextCompat.getColor(this, R.color.cm_color_FF434343), false);
    }


    private void initViewDataBinding(Bundle savedInstanceState) {
        //DataBindingUtil类需要在project的build中配置 dataBinding {enabled true }, 同步后会自动关联android.databinding包
        binding = DataBindingUtil.setContentView(this, initContentView(savedInstanceState));

        initViewModel();
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = CMBaseViewModel.class;
            }
            viewModel = setViewModel();
            if (viewModel == null) {
                // 不会进行dataBinding绑定，但是会自动初始化viewModel
                viewModel = (VM) createViewModel(modelClass);
            }
        }
        // 支持LiveData绑定xml，数据改变，UI自动会更新
        binding.setLifecycleOwner(this);
    }

    /**
     * 创建ViewModel
     * 注意：没有布局的DataBinding需求，此函数将传递variableId为0表示不进行数据绑定
     *
     * @see this#createViewModel(Class, int)
     */
    public <T extends CMBaseViewModel> T createViewModel(Class<T> cls) {
        return createViewModel(cls, 0);
    }

    /**
     * 创建ViewModel并绑定到布局DataBinding
     *
     * @param cls        Class
     * @param variableId ViewModel在布局文件的variableId，如：BR.viewModel。此值设置会自动进行数据绑定
     */
    public final <T extends CMBaseViewModel> T createViewModel(Class<T> cls, int variableId) {
        T ovm = new ViewModelProvider(this).get(cls);
        if (variableId > 0) {
            //关联ViewModel和 xml
            binding.setVariable(variableId, ovm);
        }
        return ovm;
    }

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     * <p>
     * 如果再 initViewModel 中重置了 ViewModel 的值，那么此方法不生效
     */
    public VM setViewModel() {
        return null;
    }


    /**
     * 初始化根布局
     *
     * @param savedInstanceState Bundle
     * @return 布局layout的id
     */
    public abstract int initContentView(Bundle savedInstanceState);

    /**
     * 初始化ViewModel
     * 此方法可以重置 viewModel 的结果
     */
    public void initViewModel() {
    }

    protected void initView() {
    }

    protected void initListener() {
    }

    protected void initData() {
    }

    protected void initViewObservable() {
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (binding != null) {
            binding.unbind();
        }
    }

}
